<template>
  <el-dialog
    v-model="state.visible"
    :title="props.title"
    :close-on-click-modal="false"
    :append-to-body="true"
    draggable
  >
    <div class="search-input">
      搜索：<el-autocomplete
        v-model.trim="state.searchValue"
        style="width: 50%"
        placeholder="请搜索地址"
        :fetch-suggestions="fetchMethod"
        @select="setPlace"
        clearable
        value-key="address"
      >
        <template #default="{ item }">
          <div class="title">{{ item.address + item.title }}</div>
        </template>
      </el-autocomplete>
    </div>
    <input style="display: none" id="mapSearchInput" v-model="state.searchKey" />

    <div class="map" id="t-map" style="width: 100%; height: 100%"> </div>

    <div class="bottom">
      <div>经度坐标：<br />{{ state.point?.lng }}</div>
      <div>纬度坐标：<br />{{ state.point?.lat }}</div>
      <div class="address"> 地址：<br />{{ state.searchValue || state.defaultLocal }} </div>
    </div>

    <template #footer>
      <el-button @click="handleAction(false)">取消</el-button>
      <el-button type="primary" @click="handleAction(true)"> 确定 </el-button>
    </template>
  </el-dialog>
</template>

<script setup>
const SERVICE_KEY = 'a1GYccwE6hgSHi3trKKmQFALrOhCygzQ'
const props = defineProps({
  title: {
    type: String,
    default: '地图选址'
  },
  coords: {
    type: Object,
    default: () => ({})
  },
  address: String
})

const emits = defineEmits(['located'])
defineExpose({ init })

const TMap = window.TMap
let map, markerLayer
const state = reactive({
  visible: false,
  point: {},
  searchValue: '',
  searchKey: '',
  defaultLocal: ''
})

function init() {
  state.visible = true
  console.log(props.address)
  state.searchValue = props.address

  nextTick(() => {
    const { lng, lat } = props.coords
    initMap(lat, lng)
  })
}

// 搜索
const fetchMethod = (queryString, cb) => {
  let suggestionList = []
  if (queryString?.trim()) {
    // 新建一个地点搜索类
    var suggest = new TMap.service.Suggestion({
      pageSize: 10 // 返回结果每页条目数
    })
    state.searchKey = queryString?.trim()
    suggest
      .getSuggestions({
        keyword: state.searchKey,
        location: map.getCenter() || '',
        servicesk: SERVICE_KEY
      })
      .then((result) => {
        suggestionList = result.data
        cb(suggestionList)
      })
      .catch((error) => {
        suggestionList = []
        cb(suggestionList)
      })
  } else {
    cb(suggestionList)
  }
}

// 选择地址
function setPlace(r) {
  if (!r) return
  state.searchValue = r.address + r.title
  const lat = r.location.lat
  const lng = r.location.lng
  // 可以成功更新标注点
  map.setCenter(new TMap.LatLng(lat, lng))
  updateMarker(lat, lng)
}

// 初始化点标记
function initMarker(lat, lng) {
  //创建并初始化MultiMarker
  markerLayer = new TMap.MultiMarker({
    map: map,
    styles: {
      // 点标记样式
      marker: new TMap.MarkerStyle({
        width: 20, // 样式宽
        height: 30, // 样式高
        anchor: { x: 10, y: 30 } // 描点位置
      })
    },
    geometries: [
      // 点标记数据数组
      {
        // 标记位置(纬度，经度，高度)
        position: new TMap.LatLng(lat, lng),
        id: 'marker'
      }
    ]
  })
}

// 初始化地图
function initMap(lat, lng) {
  if (!map) {
    map = new TMap.Map('t-map', {
      rotation: 20, //设置地图旋转角度
      pitch: 30, //设置俯仰角度（0~45）
      zoom: 12 //设置地图缩放级别
    })
    map.on('click', listenerClick)
  }
  if (!lng) {
    getLocation()
  } else {
    map.setCenter(new TMap.LatLng(lat, lng))
    state.point = new TMap.LatLng(lat, lng)
    if (!markerLayer) {
      initMarker(lat, lng)
    }
    updateMarker(lat, lng)
  }
}

// 地图点击
function listenerClick(evt) {
  let lat = evt.latLng.getLat()
  let lng = evt.latLng.getLng()
  updateMarker(lat, lng)
  getAddress(lat, lng)
}

// 更新标记点
function updateMarker(lat, lng) {
  if (!markerLayer) {
    initMarker(lat, lng)
  }
  // 可以成功更新标注点
  markerLayer.updateGeometries([
    {
      id: 'marker',
      position: new TMap.LatLng(lat, lng)
    }
  ])
  state.point = new TMap.LatLng(lat, lng)
}

// 获取定位
function getLocation() {
  const ipLocation = new TMap.service.IPLocation()
  ipLocation
    .locate({ servicesk: SERVICE_KEY })
    .then((result2) => {
      // 未给定ip地址则默认使用请求端的ip
      const lat = result2.result.location.lat
      const lng = result2.result.location.lng
      state.defaultLocal = result2.result.address
      map.setCenter(new TMap.LatLng(lat, lng))
      state.point = new TMap.LatLng(lat, lng)
      if (!markerLayer) {
        initMarker(lat, lng)
      }
      updateMarker(lat, lng)
      getAddress(lat, lng)
    })
    .catch((error) => {
      console.log(error)
    })
}

// ip地址解析
function getAddress(lat, lng) {
  const geocoder = new TMap.service.Geocoder()
  geocoder
    .getAddress({
      location: new TMap.LatLng(lat, lng),
      servicesk: SERVICE_KEY
    }) // 将给定的坐标位置转换为地址
    .then((result) => {
      // 显示搜索到的地址
      state.searchValue =
        result?.result?.address + result?.result?.formatted_addresses?.recommend || ''
    })
}

function handleAction(confirm) {
  state.visible = false
  if (confirm) {
    const { point, searchValue } = state
    console.log(state.searchValue)

    emits('located', { address: searchValue, point })
  }
}

onBeforeUnmount(() => {
  map?.off('click', listenerClick)
})
</script>

<style lang="scss" scoped>
.map {
  width: 100%;
  height: 50vh;
}
.search-input {
  margin-bottom: 20px;
}
.bottom {
  margin-top: 30px;
  display: flex;
  justify-content: space-between;
  > div {
    flex: 1;
  }
  .address {
    flex: 2;
  }
}
</style>
